package cn.js189.uqc.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.js189.common.constants.AbnormalConst;
import cn.js189.common.constants.Constant;
import cn.js189.common.constants.Constants;
import cn.js189.common.domain.ReqHead;
import cn.js189.common.domain.ReqInfo;
import cn.js189.common.domain.RespHead;
import cn.js189.common.domain.RespInfo;
import cn.js189.common.util.StringUtils;
import cn.js189.common.util.Utils;
import cn.js189.common.util.exception.BaseAppException;
import cn.js189.uqc.mapper.ArpuInfoMapper;
import cn.js189.uqc.redis.RedisOperation;
import cn.js189.uqc.service.IAreaBillService;
import cn.js189.uqc.service.PubAddressIpervice;
import cn.js189.uqc.util.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * 地址类查询
 */
@Slf4j
@Service
public class AreaBillServiceImpl implements IAreaBillService {
	
	@Resource
	private PubAddressIpervice pubAddressIpervice;
	@Resource
	private ArpuInfoMapper arpuInfoMapper;
	@Resource
	private RedisOperation redisOperation;
	
	@Override
	public String callNumberCountry(String reqInfo) {
		
		JSONObject response = null;
		RespInfo responseJson = new RespInfo();
		RespHead responseHead = responseJson.getHead();
		responseJson.setHead(responseHead);
		//  获得接口号流水
		String tranId = "";
		try {
			ReqInfo reqBase = BeanUtil.toBean(reqInfo, ReqInfo.class);
			ReqHead head = reqBase.getHead();// head体
			JSONObject body = reqBase.getBody();
			tranId = head.getTranId();//流水号
			String accNbr = body.getString("accNbr");//号码
			String getHNumber = pubAddressIpervice.getActionUrl(UqcAddressCodeConstants.GET_NUMBER, head.getLoginNbr())+"?accNbr="+accNbr;
			Map<String,String> headMap = new HashMap<>();
			headMap.put("X-CTG-Province-ID", "8320000");//江苏
			headMap.put("X-CTG-Lan-ID", "8320100");//暂时全部写死南京
			String rsp = HttpClientHelperForEop.getWithDcoss(getHNumber,headMap);
			JSONObject resultjson = new JSONObject();
			if(StringUtils.isEmpty(rsp)){
				resultjson.put(Constant.RESULT, "01");
				resultjson.put("msg", "企信为空");
			}else{
				resultjson = JSON.parseObject(rsp);
				resultjson.put("msg", "成功调用");
				resultjson.put(Constant.RESULT, "0");
			}
			response = Utils.builderResponse(resultjson.toString(), responseHead, responseJson, tranId, "result", "", "msg");
			if(body.containsKey(Constants.UQCENCFLAG)){
				response = EuaCacheUtil.getEncResponse(response,head);
			}
		} catch (Exception e) {
			response = Utils.dealExceptionResp(responseHead, tranId, responseJson);
			return response.toString();
		}
		return response.toString();
		
	}
	
	@Override
	public String callNewAreaCodeBasic(String reqInfo) {
		
		JSONObject response = null;
		RespInfo responseJson = new RespInfo();
		RespHead responseHead = responseJson.getHead();
		responseJson.setHead(responseHead);
		//  获得接口号流水
		String tranId = "";
		try {
			
			JSONObject requestJson = JSON.parseObject(reqInfo);
			ReqInfo data = BeanUtil.toBean(requestJson, ReqInfo.class);
			ReqHead head = data.getHead();// head体
			JSONObject body = data.getBody();
			tranId = head.getTranId();//流水号
			String accNbr = body.getString("accNbr");//号码
			if(accNbr.length()!=11){//如果手机号码长度不是11位，直接返回入参校验失败
				throw new BaseAppException(AbnormalConst.PARAM_ERROR, "系统错误", null, null);
			}
			Pattern pattern = Pattern.compile("[0-9]+");
			boolean flag = pattern.matcher(accNbr).matches();
			//如果不全是数字，抛错
			if(!flag){
				throw new BaseAppException(AbnormalConst.PARAM_ERROR, "系统错误", null, null);
			}
			String begin = accNbr.substring(0, 1);
			//首字母不是1
			if(!"1".equals(begin)){
				throw new BaseAppException(AbnormalConst.PARAM_ERROR, "系统错误", null, null);
			}
			String accNbrPart = accNbr.substring(0, 7);
			String resultJsonStr = redisOperation.getForString("getAreaCode2_"+accNbrPart);
			if(CharSequenceUtil.isNotBlank(resultJsonStr)){
				JSONObject resultJson = JSON.parseObject(resultJsonStr);
				JSONObject responseHead2  = BSSHelper.getRspInfo("00","success");
				response = new JSONObject();
				response.put("head", responseHead2);
				response.put("body", resultJson);
			}else{
				String oldResult = this.callNewAreaCode(reqInfo);
				JSONObject oldResultJson = JSON.parseObject(oldResult);
				if("00".equals(oldResultJson.getJSONObject("head").getString("status"))){
					JSONObject bodyForRedis = oldResultJson.getJSONObject("body");
					String areaCode = bodyForRedis.getString("areaCode");
					bodyForRedis.put("city_name", StringUtils.getAreaNameByAreaCode(areaCode));
					if(StringUtils.getAreaNameByAreaCode(areaCode)!=null){
						bodyForRedis.put("province_name", "江苏");//计费的接口只能查到江苏的号段，但是无法查到对应运营商
					}
					bodyForRedis.put("hcode", accNbrPart);
					redisOperation.setForString("getAreaCode2_"+accNbrPart, oldResultJson.getJSONObject("body").toString());
					return  oldResultJson.toString();
				}else{
					//如果接口也查不出来，那就查老的最开始的数据库存的（这块查不出来只可能是外省号码，直接查老redis，不影响系统返回）
					resultJsonStr = redisOperation.getForString("getAreaCode_"+accNbrPart);
					if(CharSequenceUtil.isNotBlank(resultJsonStr)){
						JSONObject resultJson = JSON.parseObject(resultJsonStr);
						JSONObject responseHead2  = BSSHelper.getRspInfo("00","success");
						response = new JSONObject();
						response.put("head", responseHead2);
						response.put("body", resultJson);
					}else{
						return  oldResultJson.toString();
					}
				}
			}
		} catch(BaseAppException e) {
			response = Utils.dealBaseAppExceptionResp(responseHead, tranId, responseJson);
			log.debug("区号查询-101120 BaseAppException :{}" , e.getMessage());
			return response.toString();
		} catch (Exception e) {
			response = Utils.dealExceptionResp(responseHead, tranId, responseJson);
			log.debug("区号查询-101120 Exception :{}" , e.getMessage());
			return response.toString();
		}
		return response.toString();
	}
	
	@Override
	public String callNewAreaCode(String params) {
		JSONObject response = null;
		RespInfo responseJson = new RespInfo();
		RespHead responseHead = responseJson.getHead();
		responseJson.setHead(responseHead);
		//  获得接口号流水
		String tranId = "";
		try {
			ReqInfo reqInfo = BeanUtil.toBean(params, ReqInfo.class);
			JSONObject body = reqInfo.getBody();
			
			String result = BSUtils.callNewAreaCodeNew(reqInfo);
			ReqHead reqHead = reqInfo.getHead();
			return EuaCacheUtil.buildBillResponse(body, reqHead, result);
		} catch (Exception e) {
			response = Utils.dealExceptionResp(responseHead, tranId, responseJson);
			log.debug("区号查询-10112 Exception :{}" , e.getMessage());
			return response.toString();
		}
	}
	
	@Override
	public String getArpuByPhoneNbr(String reqParams) {
		JSONObject response = null;
		log.debug("getArpuByPhoneNbr:{}" , reqParams);
		RespInfo responseJson = new RespInfo();
		RespHead respHead = new RespHead();
		//  获得接口号流水
		String tranId = "";
		try {
			ReqInfo reqInfo = BeanUtil.toBean(reqParams, ReqInfo.class);
			ReqHead head = reqInfo.getHead();// head体
			JSONObject body = reqInfo.getBody();
			tranId = head.getTranId();//流水号
			String phoneNbr = body.getString("phoneNbr");//号码
			//同步至库中的arpu_kefu不再使用，channel因为渠道问题不删除，但不起区分作用
			String channel ="KEFU".equals(head.getChannelId())?"KEFU":"NorMal";
			String responseTime = Utils.getCurrentTime();
			
			//根据渠道查询缓存arpu
			String arpu  = redisOperation.getForString("arpuInfo_"+channel+"_"+phoneNbr);//有时候会出现redis塞不进去
			if(CharSequenceUtil.isBlank(arpu)){
				log.info("开始查数据库===getArpuByPhoneNbr:{}" , phoneNbr);
				//通过数据库查询
				Map<String, String> arpuInfoMap = arpuInfoMapper.getArpuInfoByPhoneNbr(phoneNbr);
				if(arpuInfoMap!=null){
					String arpuInfo=arpuInfoMap.get("arpu");
					if(CharSequenceUtil.isBlank(arpuInfo) || "NULL".equalsIgnoreCase(arpuInfo) || arpuInfo.contains("-")){
						//数据库也没查到
						respHead.setStatus("01");
						respHead.setMsg("未查询到arpu.");
					}else{
						log.info("数据库查到===getArpuByPhoneNbr: {}", arpuInfo);
						//因为缓存不再批量刷新,redis保存一小时防止数据更新不及时
						redisOperation.setEx("arpuInfo_"+channel+"_"+phoneNbr, 60*60, arpuInfo);
						respHead.setStatus("00");
						respHead.setMsg("成功");
						body.put("arpu", arpuInfo);
					}
				}else{
					respHead.setStatus("01");
					respHead.setMsg("未查询到arpu");
				}
				respHead.setResponseId(Utils.RSP + tranId);
				respHead.setResponseTime(responseTime);
				responseJson.setBody(body);
			}else{
				log.info("缓存查到===getArpuByPhoneNbr: {}" , arpu);
				//新增 当arpu值为负数或者为"NULL"的时候返回查不到
				if("NULL".equalsIgnoreCase(arpu) || arpu.contains("-")){
					respHead.setStatus("01");
					respHead.setMsg("未查询到arpu");
				}else{
					respHead.setStatus("00");
					respHead.setMsg("成功");
					body.put("arpu", arpu);
				}
				respHead.setResponseId(Utils.RSP + tranId);
				respHead.setResponseTime(responseTime);
				responseJson.setBody(body);
			}
			response = (JSONObject) JSON.toJSON(responseJson);
		}  catch (Exception e) {
			response = Utils.dealExceptionResp(respHead, tranId, responseJson);
			log.error(e.getMessage());
			return response.toString();
		}
		return response.toString();
	}
	
	@Override
	public String getGoodsIdByAccNbrFK(String reqParams) {
		JSONObject response = null;
		RespInfo respInfo = new RespInfo();
		
		
		String tranId = "";
		try {
			ReqInfo reqInfo = BeanUtil.toBean(reqParams, ReqInfo.class);
			ReqHead head = reqInfo.getHead();
			JSONObject body = reqInfo.getBody();
			
			tranId = head.getTranId();//流水号
			String phoneNum = body.getString("phoneNum");//号码
			
			String goodsNum = redisOperation.getForString("fkGoods_" + phoneNum);
			if(CharSequenceUtil.isBlank(goodsNum)){
				goodsNum = "";
			}
			
			Map<String, String> map = new HashMap<>();
			map.put("phoneNum", phoneNum);
			
			if (StringUtils.isEmpty(goodsNum) || "null".equalsIgnoreCase(goodsNum)) {
				JSONObject responseHead2 = BSSHelper.getRspInfo("007","DissatisfySelectTerm");
				response = new JSONObject();
				response.put("head", responseHead2);
				
				map.put("respCode", "007");
				map.put("goodsNum", "");
			}
			else {
				String code = "00";
				String msg = "success";
				map.put("respCode", "00");
				map.put("goodsNum", goodsNum);
				
				JSONObject responseHead2 = BSSHelper.getRspInfo(code, msg);
				response = new JSONObject();
				response.put("head", responseHead2);
			}
			response.put("body", map);
		} catch (Exception e) {
			response = Utils.dealExceptionResp(respInfo.getHead(), tranId, respInfo);
			log.error("getGoodsIdByAccNbrFK Exception :{}" , e.getMessage());
			return response.toString();
		}
		return response.toString();
	}
	
	@Override
	public String getProdExtendInfo(String reqParams) {
		JSONObject response = null;
		RespInfo responseJson = new RespInfo();
		RespHead respHead = new RespHead();
		String responseTime = Utils.getCurrentTime();
		
		String tranId = "";
		try {
			ReqInfo reqInfo = BeanUtil.toBean(reqParams,ReqInfo.class);
			ReqHead head = reqInfo.getHead();
			JSONObject body = reqInfo.getBody();
			
			tranId = head.getTranId();//流水号
			
			String latnId = body.getString("latnId");//本地网Id
			String pdInstId = body.getString("pdInstId");//产品实例Id
			JSONObject paramJson = new JSONObject();
			paramJson.put("latnId", latnId);
			paramJson.put("pdInstId", pdInstId);
			
			String url = pubAddressIpervice.getActionUrl(UqcAddressCodeConstants.GET_PROD_EXTEND_INFO,head.getLoginNbr());
			log.info("getProdExtendInfo paramJson=:{}" ,paramJson );
			String res = HttpClientHelperForEop.postWithMNPWithHeader(url, paramJson.toJSONString(), new HashMap<>());
			log.info("getProdExtendInfo res=:{}" ,res );
			if (StringUtils.isEmpty(res)) {
				respHead.setStatus("01");
				respHead.setMsg("返回数据为空，无法解析");
				respHead.setResponseId(Utils.RSP + tranId);
				respHead.setResponseTime(responseTime);
				responseJson.setBody(body);
				response = (JSONObject) JSON.toJSON(responseJson);
				return response.toString();
			}
			JSONObject resObj = JSON.parseObject(res);
			
			String success = resObj.getString("success");
			if ("true".equals(success)) {
				//成功
				respHead.setStatus("00");
				respHead.setMsg("成功");
				respHead.setResponseId(Utils.RSP + tranId);
				respHead.setResponseTime(responseTime);
				
				JSONObject prodExtendInfo = resObj.getJSONObject("payload");
				body.put("prodExtendInfo", prodExtendInfo);
				responseJson.setBody(body);
			}else{
				//其他情况失败
				respHead.setStatus("01");
				respHead.setMsg("返回数据异常，无法解析"+res);
				respHead.setResponseId(Utils.RSP + tranId);
				respHead.setResponseTime(responseTime);
				responseJson.setBody(body);
			}
			response = (JSONObject) JSON.toJSON(responseJson);
		} catch (Exception e) {
			response = Utils.dealExceptionResp(respHead, tranId, responseJson);
			log.error("getProdExtendInfo Exception :{}" , e.getMessage());
			return response.toString();
		}
		return response.toString();
	}
	
}
